﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace idleQuest2010
{
    public class RandomGenerator
    {
        Random rand1;
        Random rand;
        Avatar pc;          //need this to get player's current level (to determine strength of items and monsters to generate)
        string[] monsterNames;      //a list of possible monster type names
        string[] monsterDescriptors;     //a list of possible monster descriptors
        //item type names (each item type has a different possible set of names):
        string[] weaponNames;
        string[] offhandNames;
        string[] torsoNames;
        string[] headNames;
        string[] handsNames;
        string[] feetNames;
        string[] fingerNames;
        string[] neckNames;
        string[] backNames;
        string[] trashNames;

        string[] itemPrefixDesc;    //item descriptor terms (placed before the name)
        string[] itemSuffixDesc;    //item descriptor terms (after the name, i.e. large sword of greatness)

        char[] delimiterChars = { ',', '.', ':', '\t', '\n' };

        public RandomGenerator(int seed, Avatar player)
        {
            rand1 = new Random(seed);
            rand = new Random(rand1.Next());    //randomized seed for more random results
            pc = player;

            string temp;
            string path = "words/";

            StreamReader read_mNames, read_mDescript, read_wNames, read_oNames, read_tNames, read_hnNames, read_fNames, read_hdNames, read_fnNames, read_bNames, read_nNames, read_trNames, read_iPrefix, read_iSuffix;
            read_mNames = new StreamReader(path + "monsternames.txt");
            temp = read_mNames.ReadToEnd();
            monsterNames = temp.Split(delimiterChars);     //parse text file into array so we can select a word later
            read_mNames.Close();
            read_mDescript = new StreamReader(path + "monsterdescriptors.txt");
            temp = read_mDescript.ReadToEnd();
            monsterDescriptors = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_mDescript.Close();
            read_wNames = new StreamReader(path + "weaponnames.txt");
            temp = read_wNames.ReadToEnd();
            weaponNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_wNames.Close();
            read_oNames = new StreamReader(path + "offhandnames.txt");
            temp = read_oNames.ReadToEnd();
            offhandNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_oNames.Close();
            read_tNames = new StreamReader(path + "torsonames.txt");
            temp = read_tNames.ReadToEnd();
            torsoNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_tNames.Close();
            read_hdNames = new StreamReader(path + "headnames.txt");
            temp = read_hdNames.ReadToEnd();
            headNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_hdNames.Close();
            read_hnNames = new StreamReader(path + "handsnames.txt");
            temp = read_hnNames.ReadToEnd();
            handsNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_hnNames.Close();
            read_fNames = new StreamReader(path + "feetnames.txt");
            temp = read_fNames.ReadToEnd();
            feetNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_fNames.Close();
            read_fnNames = new StreamReader(path + "fingernames.txt");
            temp = read_fnNames.ReadToEnd();
            fingerNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_fnNames.Close();
            read_bNames = new StreamReader(path + "backnames.txt");
            temp = read_bNames.ReadToEnd();
            backNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_bNames.Close();
            read_nNames = new StreamReader(path + "necknames.txt");
            temp = read_nNames.ReadToEnd();
            neckNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_nNames.Close();
            read_trNames = new StreamReader(path + "trashnames.txt");
            temp = read_trNames.ReadToEnd();
            trashNames = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_trNames.Close();
            read_iPrefix = new StreamReader(path + "itemprefixdesc.txt");
            temp = read_iPrefix.ReadToEnd();
            itemPrefixDesc = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_iPrefix.Close();
            read_iSuffix = new StreamReader(path + "itemsuffixdesc.txt");
            temp = read_iSuffix.ReadToEnd();
            itemSuffixDesc = temp.Split(delimiterChars);    //parse text file into array so we can select a word later
            read_iSuffix.Close();
        }

        public Item generateItem()      //generate random item with random type
        {
            Type enumType = Type.GetType("idleQuest2010.itemType");
            int numElementsInEnum = Enum.GetValues(enumType).Length;
            int iT = rand.Next(0, numElementsInEnum);        //find the number of possible item types and pick a random type
            return generateItem((itemType)iT);
        }

        public Item generateItem(itemType iT)       //generate random item of a given type
        {
            int minValue = pc.level - 30;       //minimum value that an item might have
            int maxValue = pc.level + 10;       //max value that an item might have  (changes with level, so you will get stronger items as you level up)
            if (minValue <= 0) minValue = 1;    //real items don't have value of 0 or less (maxvalue will never be 0 or less)

            int value = rand.Next(minValue, maxValue + 1);  //pick a value for the item

            int nameNum;
            string itemNameType;

            switch (iT)
            {
                case itemType.Weapon:
                    nameNum = rand.Next(0, weaponNames.Length);
                    itemNameType = weaponNames[nameNum];
                    break;
                case itemType.Offhand:
                    nameNum = rand.Next(0, offhandNames.Length);
                    itemNameType = offhandNames[nameNum];
                    break;
                case itemType.Torso:
                    nameNum = rand.Next(0, torsoNames.Length);
                    itemNameType = torsoNames[nameNum];
                    break;
                case itemType.Head:
                    nameNum = rand.Next(0, headNames.Length);
                    itemNameType = headNames[nameNum];
                    break;
                case itemType.Hands:
                    nameNum = rand.Next(0, handsNames.Length);
                    itemNameType = handsNames[nameNum];
                    break;
                case itemType.Feet:
                    nameNum = rand.Next(0, feetNames.Length);
                    itemNameType = feetNames[nameNum];
                    break;
                case itemType.Finger:
                    nameNum = rand.Next(0, fingerNames.Length);
                    itemNameType = fingerNames[nameNum];
                    break;
                case itemType.Back:
                    nameNum = rand.Next(0, backNames.Length);
                    itemNameType = backNames[nameNum];
                    break;
                case itemType.Neck:
                    nameNum = rand.Next(0, neckNames.Length);
                    itemNameType = neckNames[nameNum];
                    break;
                case itemType.Trash:
                    nameNum = rand.Next(0, trashNames.Length);
                    itemNameType = trashNames[nameNum];
                    break;
                default:
                    nameNum = 0;
                    itemNameType = "";
                    break;
            }

            string name;
            if (iT != itemType.Trash)
            {
                int descPreNum = rand.Next(0, itemPrefixDesc.Length);     //pick a random item prefix
                int descSufNum = rand.Next(0, itemSuffixDesc.Length);     //pick a random item suffix
                name = itemPrefixDesc[descPreNum] + " " + itemNameType + " of " + itemSuffixDesc[descSufNum];
            }
            else name = itemNameType;

            Item i = new Item(name, iT, value);
            return i;
        }

        public Monster generateMonster()            //generate monster with random name
        {
            string name = monsterDescriptors[rand.Next(0, monsterDescriptors.Length)] + " " + monsterNames[rand.Next(0, monsterNames.Length)];      //put together a name with a random descriptor and type            
            
            Monster m = new Monster(name, pc.level);
            return m;
        }

        //TODO: generate phrases for various events
    }
}
